package cn.dakaqi.utils.qrcode;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Decoder;

import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Hashtable;

/**
 * Created by chunyang on 2016/4/21.
 */
public class QRCode
{
    private final String text;
    private ImageType imageType = ImageType.PNG;
    private int width = 125;
    private int height = 125;

    private static final String CHARSET = "utf-8";
    private static final String FORMAT_NAME = "JPG";
    // 二维码尺寸
    private static final int QRCODE_SIZE = 300;
    // LOGO宽度
    private static final int WIDTH = 60;
    // LOGO高度
    private static final int HEIGHT = 60;

    private QRCode(String text) {
        this.text = text;
    }

    public static QRCode from(String text)
    {
        return new QRCode(text);
    }

    public QRCode to(ImageType imageType)
    {
        this.imageType = imageType;
        this.width = QRCODE_SIZE;
        this.height = QRCODE_SIZE;
        return this;
    }

    public QRCode withSize(int width, int height)
    {
        this.width = width;
        this.height = height;
        return this;
    }

    public File file()
    {
        File file;
        try
        {
            file = createTempFile();
            MatrixToImageWriter.writeToFile(createMatrix(), this.imageType.toString(), file);
        } catch (Exception e) {
            throw new QRGenerationException("Failed to create QR image from text due to underlying exception", e);
        }

        return file;
    }

    public ByteArrayOutputStream stream()
    {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        try {
            MatrixToImageWriter.writeToStream(createMatrix(), this.imageType.toString(), stream);
        } catch (Exception e) {
            throw new QRGenerationException("Failed to create QR image from text due to underlying exception", e);
        }

        return stream;
    }
    public BufferedImage bufferedImage()
    {
        BufferedImage bufferedImage = null;
        try {

            bufferedImage = MatrixToImageWriter.toBufferedImage(createMatrix());
        } catch (Exception e) {
            throw new QRGenerationException("Failed to create QR image from text due to underlying exception", e);
        }

        return bufferedImage;
    }
    private BitMatrix createMatrix() throws WriterException
    {
        //return new QRCodeWriter().encode(this.text, BarcodeFormat.QR_CODE, this.width, this.height);
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        hints.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix = new MultiFormatWriter().encode(this.text,BarcodeFormat.QR_CODE, this.width, this.height, hints);
        return bitMatrix;
    }

    private File createTempFile() throws IOException
    {
        File file = File.createTempFile(this.text, "-" + this.imageType.toString().toLowerCase());
        file.deleteOnExit();
        return file;
    }
    // base64字符串转化成图片
    public static boolean GenerateImage(String fileName,String imgStr)
    {
        // 对字节数组字符串进行Base64解码并生成图片
        if (imgStr == null) // 图像数据为空
            return false;
        BASE64Decoder decoder = new BASE64Decoder();
        try
        {
// Base64解码
            byte[] b = decoder.decodeBuffer(imgStr);
            for (int i = 0; i < b.length; ++i)
            {
                if (b[i] < 0)
                {// 调整异常数据
                    b[i] += 256;
                }
            }// 生成jpeg图片
            String imgFilePath = "d:\\passport\\"+fileName+".png";// 新生成的图片
            OutputStream out = new FileOutputStream(imgFilePath);
            out.write(b);
            out.flush();
            out.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    public static void main(String[] args)
    {
        test();
    }
    public static void test()
    {
//        String qrtext = "张春洋";
//        ByteArrayOutputStream out = QRCode.from(qrtext).to(ImageType.PNG).stream();
//        byte[] data = out.toByteArray();
//        System.out.println(new String(Base64.encodeBase64(data)));

//        String no = "31000000100000";
//        for(int i=1;i<=2000;i++)
//        {
//            String code = "";
//            try
//            {
//                if(i<10)
//                  code = no +"000"+i;
//                else if(i>=10 && i<100)
//                    code = no +"00"+i;
//                else if(i>=100 && i<1000)
//                    code = no +"0"+i;
//                else
//                    code = no+i;
//            ByteArrayOutputStream out = QRCode.from(code).withSize(54,54).stream();
//            byte[] data = out.toByteArray();
//                String imageStr = new String(Base64.encodeBase64(data));
//            System.out.println(imageStr);
//                GenerateImage(code,imageStr);
//            } catch (Exception e)
//            {
//                e.printStackTrace();
//            }
//        }
        String temp = "611298;673108";
        String no = "310000001000";
        String temps[] = temp.split(";");
        System.out.println(temps.toString());
        for(String str:temps)
        {
            try
            {
                ByteArrayOutputStream out = QRCode.from(no+str).withSize(54,54).stream();
                byte[] data = out.toByteArray();
                String imageStr = new String(Base64.encodeBase64(data));
                GenerateImage(no+str,imageStr);
            } catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}
